package com.rcloud.server.sealtalk.controller;


import com.rcloud.server.sealtalk.constant.Constants;
import com.rcloud.server.sealtalk.constant.ErrorCode;
import com.rcloud.server.sealtalk.constant.SmsServiceType;
import com.rcloud.server.sealtalk.constant.TokenConstant;
import com.rcloud.server.sealtalk.controller.param.InviteUserParam;
import com.rcloud.server.sealtalk.domain.Users;
import com.rcloud.server.sealtalk.exception.ServiceException;
import com.rcloud.server.sealtalk.manager.UserManager;
import com.rcloud.server.sealtalk.model.response.APIResult;
import com.rcloud.server.sealtalk.model.response.APIResultWrap;
import com.rcloud.server.sealtalk.service.UsersService;
import com.rcloud.server.sealtalk.util.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zc
 * @date 2022/4/12 5:36 上午
 */
@Api(tags = "用户websocket信息相关接口")
@RestController
@RequestMapping("/v1/common")
public class LoginCommonController extends BaseController {
    @Autowired
    private UserManager userManager;

    @Autowired
    private UsersService usersService;

    @Autowired
    private RedisUtils redisUtils;

    @Value("${sealtalk-config.token.secret}")
    private String tokenSecret; //token密钥

    @Value("${sealtalk-config.token.expiretime}")
    private Long tokenExpireTime;//token过期时间 单位分钟


    @ApiOperation("websocket登录的接口")
    @PostMapping("/websocket/login")
    @ResponseBody
    public APIResult<Object> login(@RequestBody InviteUserParam userParam, HttpServletResponse response) throws ServiceException {
        String region = userParam.getRegion();
        String mobile = userParam.getMobile();
        String smsCode = userParam.getSmsCode();
        String recommendCode = userParam.getRecommendCode();
        //判断邀请信息的正确性
        if (recommendCode != null ) {
            int userId = ShareCodeUtil.codeToId(userParam.getRecommendCode()).intValue();
            Users user = userManager.getUser(userId);
            if (user == null) {
                throw new ServiceException(ErrorCode.CAN_NOT_QUERY_RECOMMEND_USER);
            }
        }
        region = MiscUtils.removeRegionPrefix(region);
        ValidateUtils.checkRegion(region);
        ValidateUtils.checkCompletePhone(mobile);
        Users users = userManager.verifyCodeRegisterForWebSocket(region, mobile, smsCode, recommendCode, SmsServiceType.YUNPIAN);
        //设置cookie  userId加密存入cookie
        //登录成功后的其他请求，当前登录用户useId获取从cookie中获取
        setCookie(response, users.getId());
        Map<String, Object> resultMap = new HashMap<>();
        //创造token
        String token = JwtUtils.createToken(users, tokenSecret);
        //设置用户缓存
        redisUtils.set(TokenConstant.LOGIN_TOKEN_KEY + users.getId(), token, tokenExpireTime);
        resultMap.put("id", users.getId());
        resultMap.put("token", token);
        resultMap.put("nickName", users.getNickname());
        resultMap.put("inviteCode", users.getInviteCode());
        //对result编码
        return APIResultWrap.ok(resultMap);
    }
    @ApiOperation("websocket获取用户信息的接口")
    @PostMapping("/user/info")
    @ResponseBody
    public APIResult<Object> queryUser(HttpServletRequest request, HttpServletResponse response) throws ServiceException {
        //获取当前登录用户ID
        String token = JwtUtils.getToken(request);
        Long userId = JwtUtils.getUserIdToken(token, tokenSecret);
        Users user = userManager.getUser(userId.intValue());
        return APIResultWrap.ok(user);
    }


//    @PostMapping("/updateAllUserCode")
//    @ResponseBody
    private APIResult<Object> updateAllUserCode() {
        List<Users> users = usersService.getByExample(new Example(Users.class));
        Users updateUser = new Users();
        for (Users user : users) {
            updateUser.setId(user.getId());
            updateUser.setInviteCode(ShareCodeUtil.toSerialCode(user.getId().longValue()));
            usersService.updateByPrimaryKeySelective(updateUser);
        }
        return APIResultWrap.ok();
    }


    /**
     * 设置AuthCookie
     *
     * @param response
     * @param userId
     */
    private void setCookie(HttpServletResponse response, int userId) {
        int salt = RandomUtil.randomBetween(1000, 9999);
        String text = salt + Constants.SEPARATOR_NO + userId + Constants.SEPARATOR_NO + System.currentTimeMillis();
        byte[] value = AES256.encrypt(text, sealtalkConfig.getAuthCookieKey());
        Cookie cookie = new Cookie(sealtalkConfig.getAuthCookieName(), new String(value));
        cookie.setHttpOnly(true);
        cookie.setDomain(sealtalkConfig.getAuthCookieDomain());
        cookie.setMaxAge(Integer.valueOf(sealtalkConfig.getAuthCookieMaxAge()));
        cookie.setPath("/");
        response.addCookie(cookie);
    }
}
